const app = require('j7/app');
const utils = require('j7/utils');
const bcutils = require('j7/bcutils');
const bcconst = require('common/bcconst');
const metaFactory = require('../metadata/factory');
const serviceFactory = require('../services/factory');

async function mintHero(session) {
  try {
    const accountAddress = bcutils.toNormalAddress(session.request('account_address'));
    const netId = session.request('net_id');
    const tokenIds = session.request('token_ids').split(',');
    const nftAddress = bcutils.toNormalAddress(session.request('nft_address'));
    const toAddress = bcutils.toNormalAddress(session.request('to_address'));
    const bc = serviceFactory.create('BlockChain');
    {
      const ret = await bc.init(netId);
      if (!ret) {
        session.rspErr(500, 'net_id error');
        return;
      }
    }
    {
      if (!bc.isValidAddress(accountAddress)) {
        session.rspErr(500, 'accountAddress error');
        return;
      }
    }
    {
      if (!bc.isValidAddress(toAddress)) {
        session.rspErr(500, 'toAddress error');
        return;
      }
    }

    const userAddress = bc.getUserAddress();
    const thisContractAddress = bc.getContractAddressByName('NFTLock');
    const instance = bc.getInstanceByName('NFTLock');

    const transModel = session.createModel('Transaction');

    {
      const heroAddress = bcutils.toNormalAddress(bc.getNftAddress(bcconst.BC_NFT_HERO));
      const normalHeroAddress = bcutils.toNormalAddress(bc.getNftAddress(bcconst.BC_NFT_NORMAL_HERO));
      if (!nftAddress) {
        session.rspErr(101, 'nft_address param error2');
        return;
      }
      console.log(toAddress, heroAddress, normalHeroAddress);
      if (!(nftAddress == heroAddress || nftAddress == normalHeroAddress)) {
        session.rspErr(500, 'nft_address is not hero or normalhero address');
        return;
      }
    }

    const {err, seqId} = await transModel.add(accountAddress, session.requestToJson(), netId);
    if (err) {
      console.log(err);
      session.rspErr(500, 'server internal error');
      return;
    }

    const nowTime = utils.getUtcTime();
    const transId = bcutils.genTransId
    (
      bcconst.BC_FUNC_COMMON,
      nowTime,
      seqId,
      [
      ]
    );
    await transModel.update
    (
      seqId,
      [
        ['trans_id', transId]
      ]);
    const nonce = transId;
    const nftList = [];
    tokenIds.forEach(ele => {
      nftList.push([
        ele,
        toAddress,
        true
      ]);
    });
    const nftListArr = [];
    nftList.forEach((item) => {
      nftListArr.push(item[0].toString());
      nftListArr.push(item[1].toString());
      nftListArr.push('0x01');
    });
    const signature = await bc.soliditySha3Sign(
      accountAddress,
      nftAddress,
      thisContractAddress,
      netId,
      nowTime,
      nonce,
      ...nftListArr,
    );
    console.log(
      accountAddress,
      nftAddress,
      thisContractAddress,
      netId,
      nowTime,
      nonce,
      nftListArr,
      signature
    );

    let data = instance.methods.unlockOrMint
    (
      nftAddress,
      nftList,
      nowTime,
      nonce,
      signature).encodeABI();

    session.rspData({
      'trans_id' : transId,
      'trans_req': {
        'to': thisContractAddress,
        'data': data
      }
    });
  } catch (e) {
    session.rspErr(1, 1);
    utils.safeDumpErrStack(e);
    console.log(e);
  }
}

function init() {
  app.registerHandler('BcService', 'mintHero', mintHero);
}

exports.init = init;
